package com.wqm.step.dao.impl;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import com.wqm.step.common.utils.HibernateUtils;
import com.wqm.step.dao.HQLDao;
import com.wqm.step.pojo.Customer;
import com.wqm.step.pojo.Order;

@Repository
public class HQLDaoImpl extends HibernateDaoSupport implements HQLDao {

	@Autowired
	public void setSuperSessionFactory(SessionFactory factory) {
		super.setSessionFactory(factory);
	}

	/**
	 * 向一对多数据表中添加10条数据
	 */
	public void saveDataInDatabase(Customer c) {
		Session session = this.getSessionFactory().getCurrentSession();
		for (int i = 0; i < 10; i++) {
			Order order = new Order();
			order.setMoney(2000d + i * 10);
			order.setAddress("成都");
			order.setC(c);
			session.save(order);
		}
	}

	/**
	 * 基本查询：查询所有客户及客户下的所有订单
	 */
	@SuppressWarnings("unchecked")
	public List<Customer> findAllCustomer() {
		Session session = this.getSessionFactory().getCurrentSession();
		// from是关键字，后面是类名,关键字是不区分大小写，但是类名是区分
		String hql = "from Customer";
		return session.createQuery(hql).list();
	}

	/**
	 * 排序查询：查询所有的订单，并根据订单的价格排序
	 */
	@SuppressWarnings("unchecked")
	public List<Order> findOrderSort() {
		Session session = this.getSessionFactory().getCurrentSession();
		String hql = "from Order order by money asc";// desc 降序 asc 升序(默认)
		List<Order> list = session.createQuery(hql).list();
		System.out.println(list.toString());
		return list;
	}

	/**
	 * 条件查询 /多条件查询 (查询Order表)
	 * 查询订单价格在2020到2070之间的订单
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<Order> findCondition() {
		// 这里测试一下，自己编写的工具类
		//这个不行啊， 这个工具类要读取的是hibernate自己hibernate.cfg.xml中的信息，这里没有使用这个配置文件
		//Session session = HibernateUtils.getCurrentSession(); 
		Session session = this.getSessionFactory().getCurrentSession();
		
		// 根据位置绑定参数
		/*String hql = "from Order where money > ?";
		List<Order> list = session.createQuery(hql).setParameter(0, 2050d).list();*/
		
		// 根据命名绑定参数
		String hql = "from Order where money >:mymoney";
		List<Order> list = session.createQuery(hql).setParameter("mymoney", 2050d).list();
		System.out.println(list);
		return list;
	}

	/**
	 * 分页查询条件查询
	 * @return
	 */
	public List<Order> findPage() {
		Session session = this.getSessionFactory().getCurrentSession();
		String sql = "from Order where money >myoney";
		Query query = session.createQuery(sql).setParameter("mymoney", 2050d);
		// 每页显示6条件 ，我们要得到第二页数据
		query.setFirstResult((2 - 1) * 6); // 设定开始位置， （要显示的页数-1）*每页显示多少条数据
		query.setMaxResults(6); // 设置条数
		
		@SuppressWarnings("unchecked")
		List<Order> list = query.list();
		System.out.println(list);
		return list;
	}

	/**
	 * 分组统计查询  这里的count(*) ,sum(money) 为聚合函数，Order 和 c 都是对象
	 */
	public List<Order> findGroup() {
		Session session = this.getSessionFactory().getCurrentSession();
		// 统计操作----统计一共有多少订单 count
		// String hql="select count(*) from Order";
		// Object count = session.createQuery(hql).uniqueResult();
		// System.out.println(count);
		
		String hql = "from Order group by c";// 根据客户分组订单
		@SuppressWarnings("unchecked")
		List<Order> list = session.createQuery(hql).list();
		System.out.println(list);
		return list;
	}

	/**
	 *  投影查询 ： 查询具体列 
	 *  	例： String hql = "from Customer"; 就是查询所有，但是如果要查询具体字段就用投影查询
	 *  	例：String hql = "select id,name from Customer";
	 */
	public List<Customer> findColumnData() {
		Session session = this.getSessionFactory().getCurrentSession();
		
		// 方法一 .查询出所有的Customer的name
		// 如果只查询一个列,得到的结果List<Object>
		// String hql = "select name from Customer";
		// List list = session.createQuery(hql).list();
		// System.out.println(list); // [张龙, 张三丰]


		// 如果是查询多列,得到的结果是List<Object[]>
		// 方法二 .查询所有的Customer的id,name
		// String hql = "select id,name from Customer";
		// List<Customer[]> list = session.createQuery(hql).list();
		/*for (Customer[] objs : list) {
			for (Customer obj : objs) {
				System.out.print(obj + " ");
			}
			System.out.println();
		}*/

		// 方法三 .使用投影将查询的结果封装到Customer对象
		String hql = "select new Customer(id,name) from Customer"; // 必须在PO类中提供对应的构造方法。另外别忘了提供无参构造
		List<Customer> list = session.createQuery(hql).list();
		System.out.println(list);
		return list;
	}
	
	

}
